package org.iori.pdf;

import java.awt.image.BufferedImage;

import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;

import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RasterFactory;
import javax.media.jai.TiledImage;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.codec.TiffImage;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.TIFFDirectory;
import com.sun.media.jai.codecimpl.TIFFImageDecoder;


public class TiffToPDF {
	
	final static String tiff_file_name= "D:/yanri/root/honban/mul-tiff/shuhan/11213.PS_72.tif";
	final static String pdf_file_name= "D:/Tiff2PDF/Tiff2PDF.pdf";
	
	final static String[] tiff_file_names = {"D:/Tiff2PDF/27769-C.tif", "D:/Tiff2PDF/27769-M.tif", "D:/Tiff2PDF/27769-Y.tif", "D:/Tiff2PDF/27769-K.tif"};
//	final static String[] tiff_file_names = {tiff_file_name};
//	final static String[] tiff_file_names = {"D:/Tiff2PDF/27769-C.tif"};
	
	static Document document;
	static PdfContentByte cb;
	
	private static int TILE_WIDTH = 128;
	private static int TILE_HEIGHT = TILE_WIDTH;

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		TifftoPDF1();
//		TifftoPDF2();
//		TifftoPDF3(pdf_file_name, tiff_file_names);
//		TifftoPDF4();
	}
	
	public static void TifftoPDF1() {
		try{
			//Read the Tiff File
			RandomAccessFileOrArray myTiffFile=new RandomAccessFileOrArray(tiff_file_name);
			//Find number of images in Tiff file
			int numberOfPages=TiffImage.getNumberOfPages(myTiffFile);
			System.out.println("Number of Images in Tiff File" + numberOfPages);
			Document TifftoPDF=new Document();
			PdfWriter.getInstance(TifftoPDF, new FileOutputStream(pdf_file_name));
			
			
			Image image = TiffImage.getTiffImage(myTiffFile, 1);
			float width = image.getWidth();
			float height = image.getHeight();
			Rectangle pageSize = new Rectangle(width, height);
			TifftoPDF.setPageSize(pageSize);
			
			TifftoPDF.open();
			
			//Run a for loop to extract images from Tiff file
			//into a Image object and add to PDF recursively
			for(int i=1;i<=numberOfPages;i++){
			    Image tempImage=TiffImage.getTiffImage(myTiffFile, i);
			    TifftoPDF.add(tempImage);
			}
			TifftoPDF.close();
			System.out.println("Tiff to PDF Conversion in Java Completed" );
		}
		catch (Exception i1){
		    i1.printStackTrace();
		}
	}
	
	public static void TifftoPDF2() throws DocumentException, IOException {
		Document document = new Document();
		PdfWriter writer = PdfWriter.getInstance(
				document,
				new FileOutputStream(pdf_file_name));
		writer.setStrictImageSequence(true);
		document.open();
		document.add(new Paragraph("Multipages tiff file"));
		Image image;
		RandomAccessFileOrArray ra = new RandomAccessFileOrArray(tiff_file_name);
		int pages = TiffImage.getNumberOfPages(ra);
		for (int i = 1; i <= pages; i++) {
			image = TiffImage.getTiffImage(ra, i);
			float width = image.getWidth();
			float height = image.getHeight();
			Rectangle pageSize = new Rectangle(width, height);
			document.setPageSize(pageSize);
			document.add(image);
			document.newPage();
		}
		document.close();
	}
	
	public static void TifftoPDF4() throws Exception {
		PlanarImage src = JAI.create("fileload", "D:/Tiff2PDF/27769-C.tif");
		
		SampleModel ssm = src.getSampleModel();
		int bands = ssm.getNumBands();
		int numBands = 0;
		numBands += bands;
		
		java.awt.Rectangle bounds = null;
		bounds = src.getBounds();
		
		SampleModel sm =
		RasterFactory.createPixelInterleavedSampleModel(
		DataBuffer.TYPE_BYTE,
		TILE_WIDTH,
		TILE_HEIGHT,
		numBands);
		ColorModel cm = PlanarImage.createColorModel(sm);
		TiledImage dst = new TiledImage(bounds.x, bounds.y, bounds.width, bounds.height, bounds.x, bounds.y, sm, cm);
		System.out.println("dst:"+dst);
		
		WritableRaster parent = dst.getWritableTile(0, 0);
		bounds = parent.getBounds();
		
		int[] bandList = new int[bands];
		
		int k = 0;
		for(int j = 0; j < bands; j++ ) {
			bandList[j] = k++;
			System.out.println(bandList[j]);
		}
		
		WritableRaster child =
				parent.createWritableChild(bounds.x, bounds.y,
						bounds.width, bounds.height,
						bounds.x, bounds.y,
						bandList);
		child.setRect(src.getData(bounds));

		System.out.println("dst:"+dst);

		dst.releaseWritableTile(0, 0);
		
		File out=new File("D:/Tiff2PDF/Tiff2PDF.jpg");
		System.out.println("dst:"+dst);
		ImageIO.write(dst, "jpg", out );
//		ImageIO.write(src, "jpg", out );
	}
	
	public static void TifftoPDF3(String filename, String[] strImages) throws Exception {
//		document = new Document();
//        FileOutputStream rech = new FileOutputStream(filename);
//        PdfWriter writer = PdfWriter.getInstance(document, rech);
//        document.open();
//        cb = writer.getDirectContent();
     
//        RandomAccessFileOrArray ra = new RandomAccessFileOrArray(strImages[0]);
//        Image image = TiffImage.getTiffImage(ra, 1);
//		float width = image.getWidth();
//		float height = image.getHeight();
//		java.awt.Rectangle bounds = new java.awt.Rectangle();
//		bounds.x = 0;
//		bounds.y = 0;
//		bounds.width = (int)width;
//		bounds.height = (int)height;

        PlanarImage[] src = new PlanarImage[strImages.length];
		int numBands = 0;
		java.awt.Rectangle bounds = null;
		int[] bands = new int[strImages.length];
		for(int i = 0; i < strImages.length; i++) {
			src[i]= JAI.create("fileload", strImages[i]);
			SampleModel ssm = src[i].getSampleModel();
			if(ssm.getTransferType() != DataBuffer.TYPE_BYTE) {
					System.out.println("Accept byte data only");
					System.exit(0);
			}
			bands[i] = ssm.getNumBands();
			numBands += bands[i];
			if(bounds == null) {
				bounds = src[i].getBounds();
			} else {
				bounds = bounds.intersection(src[i].getBounds());
				if(bounds.isEmpty()) {
					System.out.println("Null intersection");
					System.exit(0);
				}
			}
		}
		
		SampleModel sm =
		RasterFactory.createPixelInterleavedSampleModel(
		DataBuffer.TYPE_BYTE,
		TILE_WIDTH,
		TILE_HEIGHT,
		//(int)width,
		//(int)height,
		numBands);
		ColorModel cm = PlanarImage.createColorModel(sm);
		TiledImage dst = new TiledImage(bounds.x, bounds.y, bounds.width, bounds.height, bounds.x, bounds.y, sm, cm);

		int ny = dst.getNumYTiles();
		int nx = dst.getNumXTiles();
		for(int ty = 0; ty < ny; ty++) {
			for(int tx = 0; tx < nx; tx++) {
				WritableRaster parent = dst.getWritableTile(tx, ty);
				bounds = parent.getBounds();
				int startBand = 0;
				for(int i = 0; i < strImages.length; i++) {
					int[] bandList = new int[bands[i]];
					int k = startBand;
					for(int j = 0; j < bands[i]; j++ ) {
						bandList[j] = k++;
					}
					startBand += bands[i];
					WritableRaster child =
							parent.createWritableChild(bounds.x, bounds.y,
									bounds.width, bounds.height,
									bounds.x, bounds.y,
									bandList);
					child.setRect(src[i].getData(bounds));
				}
				dst.releaseWritableTile(tx, ty);
			}
		}
        
//		JAI.create("filestore",dst,"D:/Tiff2PDF/Tiff2PDF.tif","TIFF");
		
		File out=new File("D:/Tiff2PDF/Tiff2PDF.jpg");
		System.out.println("dst:"+dst);
		ImageIO.write(dst, "jpg", out );

//        document.close();
	}
	
	public static void addImage(String strImageName) throws Exception {
        System.out.println(strImageName);
        File file = new File(strImageName);
        SeekableStream stream = new FileSeekableStream(strImageName);
        TIFFDirectory dir = new TIFFDirectory(stream, 0);
        String[] names = ImageCodec.getDecoderNames(stream);
        ImageDecoder dec = ImageCodec.createImageDecoder(names[0], stream,
                null);
        int total = dec.getNumPages();
        for (int k = 0; k < total; ++k) {
            RenderedImage ri = dec.decodeAsRenderedImage(k);
            Raster ra = ri.getData();
            BufferedImage bi = new BufferedImage(ri.getColorModel(), Raster
                    .createWritableRaster(ri.getSampleModel(), ra
                            .getDataBuffer(), null), false, new Hashtable());
            Image img = Image.getInstance(bi, null, true);

            long h = 0;
            long w = 0;
            long IFDOffset = dir.getIFDOffset();
            while (IFDOffset != 0L) {
                dir = new TIFFDirectory(stream, IFDOffset, 0);
                IFDOffset = dir.getNextIFDOffset();
                h = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH);
                w = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH);
            }
            float percent = 100;
            int pos = 0;
            if (w > 895)
                percent = ((595 + 18) * 100 / w);
            if (h > 842)
                pos = (int) (842 - h * percent / 100);
            else
                pos = (int) (842 - h);
            System.out.println(percent);
            System.out.println(pos);
            img.scalePercent(percent);
            img.setAbsolutePosition(0, pos);
            System.out.println("Image: " + k);

            cb.addImage(img);
            document.newPage();
        }
        stream.close();
        file.delete();
    }

	public static void addImage2(String strImageName) throws Exception {
        System.out.println(strImageName);
        File file = new File(strImageName);
        SeekableStream stream = new FileSeekableStream(strImageName);
        TIFFDirectory dir = new TIFFDirectory(stream, 0);
        String[] names = ImageCodec.getDecoderNames(stream);
        ImageDecoder dec = ImageCodec.createImageDecoder(names[0], stream,
                null);
        int total = dec.getNumPages();
        for (int k = 0; k < total; ++k) {
            RenderedImage ri = dec.decodeAsRenderedImage(k);
            Raster ra = ri.getData();
            BufferedImage bi = new BufferedImage(ri.getColorModel(), Raster
                    .createWritableRaster(ri.getSampleModel(), ra
                            .getDataBuffer(), null), false, new Hashtable());
            Image img = Image.getInstance(bi, null, true);

            long h = 0;
            long w = 0;
            long IFDOffset = dir.getIFDOffset();
            while (IFDOffset != 0L) {
                dir = new TIFFDirectory(stream, IFDOffset, 0);
                IFDOffset = dir.getNextIFDOffset();
                h = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH);
                w = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH);
            }
            float percent = 100;
            int pos = 0;
            if (w > 895)
                percent = ((595 + 18) * 100 / w);
            if (h > 842)
                pos = (int) (842 - h * percent / 100);
            else
                pos = (int) (842 - h);
            System.out.println(percent);
            System.out.println(pos);
            img.scalePercent(percent);
            img.setAbsolutePosition(0, pos);
            System.out.println("Image: " + k);

            cb.addImage(img);
            document.newPage();
        }
        stream.close();
        file.delete();
    }
	
}
